package com.cubomagicogoias.site;

import java.text.Collator;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TreeSet;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;
import javax.servlet.http.HttpServletRequest;

import com.cubomagicogoias.model.Competicao;
import com.cubomagicogoias.model.Inscricao;
import com.cubomagicogoias.model.Modalidade;
import com.cubomagicogoias.model.Pessoa;

public class DAO {

	public static Locale BRAZIL = new Locale("pt", "BR");
	public static Collator collator = Collator.getInstance(BRAZIL);
	static {
		collator.setStrength(Collator.PRIMARY);
	}

	private DAO() {
	}

	public static DAO init(HttpServletRequest req) {
		DAO dao = (DAO) req.getAttribute("_dao_");
		if (dao == null) {
			dao = new DAO();
			req.setAttribute("_dao_", dao);
		}
		return dao;
	}

	private static PersistenceManagerFactory pmf;

	private PersistenceManager pm;

	private String lastErrorMsg;

	public PersistenceManager pm() {
		if (pm == null) {
			if (pmf == null)
				pmf = JDOHelper
						.getPersistenceManagerFactory("transactions-optional");
			pm = pmf.getPersistenceManager();
			pm.currentTransaction().begin();
		}
		return pm;
	}

	public void closeDatabase(boolean commit) {
		// request = null;
		if (pm != null) {
			try {
				pm.currentTransaction().commit();
			} catch (Exception e) {
			}
			try {
				pm.close();
			} catch (Exception e) {
			}
			pm = null;
		}
	}

	public Object persist(Object m) {
		return pm().makePersistent(m);
	}

	@SuppressWarnings("rawtypes")
	public Query query(Class c) {
		Query q = pm().newQuery(c);
		return q;
	}

	@SuppressWarnings("rawtypes")
	public Query query(Class c, String filter) {
		Query q = pm().newQuery(c, filter);
		return q;
	}

	@SuppressWarnings("rawtypes")
	public Query query(Class c, String filter, String params) {
		Query q = pm().newQuery(c, filter);
		q.declareParameters(params);
		return q;
	}

	public void commit() {
		pm().currentTransaction().commit();
		pm().currentTransaction().begin();
	}

	public Competicao procuraCompeticao(String codigo) {
		Query q = query(Competicao.class, "codigo == p_codigo",
				"String p_codigo");
		@SuppressWarnings("unchecked")
		List<Competicao> c = (List<Competicao>) q.execute(codigo);
		if (c.size() == 0)
			return null;
		return c.get(0);
	}

	public Modalidade procuraModalidade(Long id) {
		Query q = query(Modalidade.class, "id == p_id", "Long p_id");
		@SuppressWarnings("unchecked")
		List<Modalidade> m = (List<Modalidade>) q.execute(id);
		if (m.size() == 0)
			return null;
		return m.get(0);
	}

	public Modalidade procuraModalidade(String nome) {
		Query q = query(Modalidade.class, "nome == p_nome", "String p_nome");
		@SuppressWarnings("unchecked")
		List<Modalidade> m = (List<Modalidade>) q.execute(nome);
		if (m.size() == 0)
			return null;
		return m.get(0);
	}

	public Pessoa procuraPessoa(Long id) {
		Query q = query(Pessoa.class, "id == p_id", "Long p_id");
		@SuppressWarnings("unchecked")
		List<Pessoa> c = (List<Pessoa>) q.execute(id);

		if (c.size() == 0)
			return null;
		return c.get(0);
	}

	public Pessoa procuraPessoa(String email) {
		Query q = query(Pessoa.class, "email == p_email", "String p_email");
		@SuppressWarnings("unchecked")
		List<Pessoa> c = (List<Pessoa>) q.execute(email);

		if (c.size() == 0)
			return null;
		return c.get(0);
	}

	public TreeSet<Pessoa> procuraMonitores() {
		Query q = query(Pessoa.class, "monitor==true");
		@SuppressWarnings("unchecked")
		List<Pessoa> pl = (List<Pessoa>) q.execute();
		
		TreeSet<Pessoa> pls = new TreeSet<Pessoa>(
				new Comparator<Pessoa>() {
					public int compare(Pessoa o1,
							Pessoa o2) {
						return collator.compare(
								o1.getNome(), o2.getNome());
					}
				});
		
		for (Pessoa p : pl) {
			pls.add(p);
		}
		
		return pls;
	}

	public Inscricao procuraInscricao(Pessoa pessoa, Competicao competicao) {
		Query q = query(Inscricao.class,
				"pessoa == p_pessoa && competicao == p_competicao",
				"Pessoa p_pessoa, Competicao p_competicao");
		@SuppressWarnings("unchecked")
		List<Inscricao> c = (List<Inscricao>) q.execute(pessoa.getId(),
				competicao.getId());
		if (c.size() == 0)
			return null;
		return c.get(0);
	}

	public List<Modalidade> listaModalidades() {
		Query q = query(Modalidade.class);
		@SuppressWarnings("unchecked")
		List<Modalidade> c = (List<Modalidade>) q.execute();
		return c;
	}

	public Object getById(Class<?> clazz, Object id) {
		return pm.getObjectById(clazz, id);
	}

	public Date parseData(String date) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		return sdf.parse(date);
	}

	public String fmtData(Date date) {
		String FORMATO_DATA = "dd/MM/yyyy";
		SimpleDateFormat sdf = new SimpleDateFormat(FORMATO_DATA);
		return sdf.format(date);
	}
}
